#include <iostream>

#include <gtest/gtest.h>

#include "melon/client/thrift_client_pool.h"
#include "SessionService.h"
#include "im/adapters/session_adapter.h"

using imserver::SessionServiceClient;
using imserver::SessionList;
using melon::client::ClientPool;

using namespace imserver;

void * ThreadFun(void * data) {
  ClientPool<SessionServiceClient> * pool = (ClientPool<SessionServiceClient>*)data;
  
  // const char * addrs[] = {"127.0.0.1:9091", "127.0.0.1:9093"};
  // const char * addrs[] = {"127.0.0.1:9199"};
  const char * addrs[] = {"10.16.15.197:9199"};
  int addr_count = sizeof(addrs) / sizeof(char*);

  SessionServiceClient * p = NULL;
  SessionList res;

  std::map<int64_t, SessionType::type> online_map;
  // for (int i = 0; i < 1000; ++i) {
  for (int i = 0; i < 1000; ++i) {
    std::cout << "GetSessionList " << i << std::endl;
    std::string addr(addrs[i % addr_count]);
    p = pool->Alloc(addr);
    if (!p) {
      continue;
    }
    std::cout << "conn GetSessionList " << i << std::endl;

    bool success = true;
    try {

      p->AddSession(10001, "session10001");
      // std::cout << "AddSession " << i << std::endl;

      p->GetSessionList(res, 10001);

      // std::cout << "GetSessionList " << res.size() << std::endl;
      // usleep(100);

      SessionList res2;
      SessionAdapter::Instance().GetSessionList(10001, &res2, 2);
      std::cout << res2.size() << std::endl;

      p->RemoveSession(10001, "session10001");
      // usleep(100);
      p->GetSessionList(res, 10001);
      // usleep(100);
      // std::cout << res.size() << std::endl;

      std::vector<int64_t> qids;
      qids.reserve(1000);
      // usleep(100);
      for(int id = 10000; id < 11000; ++id) {
        if (id % 2 ==0) {
          p->AddSession(id, "session10001");
        }
        qids.push_back(id);
      }
      // usleep(100);
      p->GetOnlineUsers(online_map, qids);
      // std::cout << "online_map.size=" << online_map.size() << std::endl;
    } catch (const std::exception & e) {
      std::cout << addr << " error:" << e.what() << std::endl;
      success = false;
    }
    pool->Release(addr, p, success);
  }
  return NULL;
}

const int kThreadCount = 70;

int main() {
  LOG_INIT("./test.log", "DEBUG");
  ClientPool<SessionServiceClient> pool;

  pthread_t ts[kThreadCount];

  for (int i = 0; i < kThreadCount; ++i) {
    pthread_create(&ts[i], NULL, ThreadFun, &pool);
  }

  for (int i = 0; i < kThreadCount; ++i) {
    pthread_join(ts[i], NULL);
  }
  return 0;
}

